package com.ocean.common.utils;

import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.Logger;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * 解压文件
 * @author CL
 * 2019-4-24 16:34
 */
@Slf4j
public class DecompressionUtils {

	/**
     * 解压缩zipFile
     * @param file 要解压的zip文件对象
     * @param outputDir 要解压到某个指定的目录下
     * @throws IOException
     */
    public static List<String> unZip(String file,String outputDir) throws IOException {
    	List<String> list = new ArrayList<String>();
    	ZipFile zipFile = null;
        try {
            zipFile =  new ZipFile(file);
            createDirectory(outputDir,null);//创建输出目录

            Enumeration<?> enums = zipFile.getEntries();
            while(enums.hasMoreElements()){
                ZipEntry entry = (ZipEntry) enums.nextElement();
                if(entry.isDirectory()){//是目录
                    createDirectory(outputDir,entry.getName());//创建空目录
                }else{//是文件
                    File tmpFile = new File(outputDir + "/" + entry.getName());
                    createDirectory(tmpFile.getParent() + "/",null);//创建输出目录

                    InputStream in = null;
                    OutputStream out = null;
                    try{
                        in = zipFile.getInputStream(entry);;
                        out = new FileOutputStream(tmpFile);
                        int length = 0;

                        byte[] b = new byte[2048];
                        while((length = in.read(b)) != -1){
                            out.write(b, 0, length);
                        }
                        list.add(outputDir + "/" + entry.getName());
                    }catch(IOException ex){
                        throw ex;
                    }finally{
                        if(in!=null)
                            in.close();
                        if(out!=null)
                            out.close();
                    }
                }
            }
        } catch (IOException e) {
            throw new IOException("解压缩文件出现异常",e);
        } finally{
            try{
                if(zipFile != null){
                    zipFile.close();
                }
            }catch(IOException ex){
                throw new IOException("关闭zipFile出现异常",ex);
            }
        }
        return list;
    }

	/**
     * 解压.tar 文件
     * @param file 要解压的.tar文件对象
     * @param outputDir 要解压到某个指定的目录下
     * @throws IOException
     */
    public static List<String> unTar(String file,String outputDir) throws IOException{
    	List<String> list = new ArrayList<String>();
    	TarInputStream tarIn = null;
        try{
        	tarIn = new TarInputStream(new FileInputStream(new File(file)));
            createDirectory(outputDir,null);//创建输出目录
            TarEntry entry = null;
            while( (entry = tarIn.getNextEntry()) != null ){
                if(entry.isDirectory()){//是目录
                    entry.getName();
                    createDirectory(outputDir,entry.getName());//创建空目录
                }else{//是文件
                    File tmpFile = new File(outputDir + "/" + entry.getName());
                    createDirectory(tmpFile.getParent() + "/",null);//创建输出目录
                    OutputStream out = null;
                    try{
                        out = new FileOutputStream(tmpFile);
                        int length = 0;

                        byte[] b = new byte[2048];

                        while((length = tarIn.read(b)) != -1){
                            out.write(b, 0, length);
                        }
                        list.add(outputDir + "/" + entry.getName());
                    }catch(IOException ex){
                        log.info("===================解压tar格式文件出现异常："+ex +"===================");
                        throw ex;
                    }finally{

                        if(out!=null)
                            out.close();
                    }
                }
            }
        }catch(IOException ex){
            throw new IOException("解压归档文件出现异常",ex);
        } finally{
            try{
                if(tarIn != null){
                    tarIn.close();
                }
            }catch(IOException ex){
                throw new IOException("关闭tarFile出现异常",ex);
            }
        }
        return list;
    }

    /**
     * 构建目录
     * @param outputDir
     * @param subDir
     */
    public static void createDirectory(String outputDir,String subDir){
        File file = new File(outputDir);
        if(!(subDir == null || subDir.trim().equals(""))){//子目录不为空
            file = new File(outputDir + "/" + subDir);
        }
        if(!file.exists()){
              if(!file.getParentFile().exists())
                  file.getParentFile().mkdirs();
            file.mkdirs();
        }
    }

    /**
     * 解压.rar
     * @param rarFile
     * @param outDir
     * @throws Exception
     */
    public static List<String> unRar(String file,String outputDir) throws Exception {
    	List<String> list = new ArrayList<String>();
    	File outFileDir = new File(outputDir);
		if (!outFileDir.exists()) {
			outFileDir.mkdirs();
		}
		Archive archive = new Archive(new FileInputStream(file));
		FileHeader fileHeader = archive.nextFileHeader();
		while (fileHeader != null) {
			if (fileHeader.isDirectory()) {
				fileHeader = archive.nextFileHeader();
				continue;
			}
			File out = new File(outputDir + "/" + fileHeader.getFileNameString());
			if (!out.exists()) {
				if (!out.getParentFile().exists()) {
					out.getParentFile().mkdirs();
				}
				out.createNewFile();
			}
			FileOutputStream os = new FileOutputStream(out);
			archive.extractFile(fileHeader, os);
			os.close();
			fileHeader = archive.nextFileHeader();
			if (fileHeader != null) {
				list.add(outputDir + "/" + fileHeader.getFileNameString());
			}
		}
		archive.close();
		return list;
	}

    public static void main(String[] args) throws IOException {

        String inputFile = "D:\\cloud\\ncfile\\NMF_BEN_SA_INDDT_2019062600_132h_OCE.tar";
        String outFile = "D:\\cloud\\ncfile\\outfile\\NMF_BEN_SA_INDDT_2019062600_132h_OCE";



        unTar(inputFile,outFile);
    }
}
